package cn.boysoft.core.server.netty.codec;

import java.util.Map;

import javax.annotation.Resource;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import cn.boysoft.core.exception.JEEException;
import cn.boysoft.core.handler.BusinessHandler;
import cn.boysoft.core.model.message.ErrorResponse;
import cn.boysoft.core.model.message.OKResponse;
import cn.boysoft.core.model.message.Request;
import cn.boysoft.core.model.message.Response;
import cn.boysoft.core.util.XmlUtil;
/**
 * @author 付厚俊
 * CreateTime 2013-4-4 下午5:09:32
 */

public abstract class RequestHandler<R> extends SimpleChannelUpstreamHandler {
	
	private final static Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
	@Autowired
	BusinessHandler businessHandler;

	@Resource(name="jeeErrorMessageMap")
	Map<String,String> jeeErrorMessageMap;
	@SuppressWarnings("unchecked")
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		Request request = (Request) e.getMessage();
		
		LOGGER.debug("Process business method start");
		Object rt = businessHandler.execute(request);
		LOGGER.debug("Process business method end");
		//业务
		
		OKResponse response = new OKResponse();
		if(rt != null){
			response.setData(rt);
		}
		R r = this.buildReponse(response);
		e.getChannel().write(r);
		e.getFuture().addListener(ChannelFutureListener.CLOSE);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
		Throwable  throwable = e.getCause();
		ErrorResponse<Object> response= new ErrorResponse<Object>(); 
		if(throwable instanceof JEEException){
			JEEException jeeException = (JEEException)throwable;
			String errorCode = jeeException.getErrorCode();
			response.setCode(errorCode);
			String errorMessage = jeeErrorMessageMap.get(errorCode);
			if(errorMessage == null){
				LOGGER.warn(errorCode+"  have not  set error message" );
			}
			response.setMsg(errorMessage);
		}else{
			response.setCode(JEEException.SYSTEM_ERROR);
			response.setMsg(throwable.getMessage());
			LOGGER.error("System Error", throwable);
		}
		R r = this.buildReponse(response);
		Channel channel= e.getChannel();
		channel.write(r);
		e.getChannel().close();
		
	}
	
	abstract public R  buildReponse(Response<Object> r);
	

}
